package com.youlu.campus.service.platform;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.mongodb.client.result.DeleteResult;
import com.youlu.campus.base.common.CampusToken;

import com.youlu.campus.common.utils.HttpClientUtil;
import com.youlu.campus.entity.ActivityInfo;
import com.youlu.campus.entity.AppUrlLink;
import com.youlu.campus.entity.AppUserShareActivity;
import com.youlu.campus.entity.VO.req.AppUrlLinkQueryVO;
import com.youlu.campus.entity.VO.res.WechatUrlLinkResult;
import com.youlu.campus.entity.WechatConfigInfo;
import com.youlu.campus.service.activity.ActivityService;
import com.youlu.campus.service.wechat.WXacodeService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.repository.support.PageableExecutionUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.io.IOException;
import java.util.*;

/**
 * 获取小程序链接
 */

@Slf4j
@Service
public class AppUrlLinkService {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private WXacodeService wXacodeService;

    private final static String URL_LINK = "https://api.weixin.qq.com/wxa/generate_urllink?access_token=%s";

    @Value("${sys.pay.wx.mini.appId}")
    private String wxAppId;

    @Autowired
    private ActivityService activityService;

    @Value("${spring.profiles.active}")
    private String env;

    private final static String APP_MINI_TOKEN_TEST_ENV = "https://api-visitor-beta.gqgood.com/campus/public/app/token";

    /**
     * 目前只有微信小程序梦想 跳动一个APPID需要，则写死无需传参数
     *
     * @return
     */
    public String getUrlLink(String appId) {
        if (StringUtils.isBlank(appId)) {
            return "";
        }
        Query query = new Query();
        query.addCriteria(Criteria.where("appId").is(appId));
        AppUrlLink appUrlLink = this.mongoTemplate.findOne(query, AppUrlLink.class);
        if (Objects.nonNull(appUrlLink)) {
            return appUrlLink.getUrl();
        }
        return remoteUrlLink(appId, 1);
    }

    public String remoteUrlLink(String appId, Integer type) {
        log.info("【获取微信链接】appId ->{} start ");
        try {
            String accessToken = "";
            if ("test".equals(env)) {
                String result = HttpClientUtil.get(APP_MINI_TOKEN_TEST_ENV, null, null, 3000, "utf8", 3, true);
                if (StringUtils.isBlank(result)) {
                    log.error("【获取beta环境token错误】");
                    return "";
                }
                log.error("【获取beta环境token】返回结果:{}", result);
                CampusToken<String> tokeResult = JSON.parseObject(result, new TypeReference<CampusToken<String>>() {
                });
                if (tokeResult.code != 0 || StringUtils.isBlank(tokeResult.data)) {
                    log.error("【获取beta环境token错误】返回结果 code:{} msg:{}", tokeResult.code, tokeResult.msg);
                    return "";
                }
                accessToken = tokeResult.data;
            } else {
                accessToken = wXacodeService.getAccessToken();
            }

            String urlLink = String.format(URL_LINK, accessToken);
            Map<String, Object> paramMap = new HashMap();
            if (type == 2) {
                if ("wxc3211a2e49489560".equals(appId)) {
                    paramMap.put("path", "/pages/contest/detail");
                    paramMap.put("query", "activityId=63b7b7dee0375a43ded6215d");
                } else {
                    ActivityInfo activityInfo = null;
                    AppUserShareActivity appUserShareActivity = mongoTemplate.findById(appId, AppUserShareActivity.class);
                    if (Objects.nonNull(appUserShareActivity)) {
                        activityInfo = activityService.findOne(appUserShareActivity.getActivityId());
                    } else {
                        activityInfo = activityService.findOne(appId);
                    }
                    if (Objects.isNull(activityInfo)) {
                        if (2 == appUserShareActivity.getPageType()) {
                            paramMap.put("path", "/pages/tabbar/tabbar");
                            paramMap.put("query", "activityChannelId=" + appUserShareActivity.getActivityChannelId());
                        } else {
                            paramMap.put("path", "/pages/contest/detail");
                            paramMap.put("query", "activityId=63b7b7dee0375a43ded6215d");
                        }
                    } else {
                        switch (activityInfo.getType()) {
                            case "wx-mini-dreambeat-contest":
                                paramMap.put("path", "/pages/contest/detail");
                                break;
                            case "video":
                                paramMap.put("path", "/pages/activity/detail");
                                break;
                            case "kos":
                                paramMap.put("path", "/pages/kos/kos-detail");
                                break;
                            case "recruitment":
                                paramMap.put("path", "/pages/recruitment");
                                break;
                            case "daka":
                                paramMap.put("path", "/pages/check-in/detail");
                                break;
                            case "continuous-daka":
                                paramMap.put("path", "/pages/continuous-check-in/detail");
                                break;
                            default:
                                paramMap.put("path", "/pages/recruitment");
                        }

                        if (Objects.nonNull(appUserShareActivity)) {
                            Integer shareLinkType = appUserShareActivity.getShareLinkType();
                            switch (shareLinkType) {
                                case 1://个人分拥
                                    String param =
                                            "activityId=" + appUserShareActivity.getActivityId() + "&taskId=" + appUserShareActivity.getTaskId() +
                                                    "&sharedByUserId=" + appUserShareActivity.getUserId() + "&sharedByOpenId" +
                                                    "=" + appUserShareActivity.getSharedByOpenId();
                                    log.info("分销员第三方应用：{}", param);
                                    paramMap.put("query", param);
                                    break;
                                case 2:
                                    //领取电子证书
                                    log.info("领取电子证书");
                                    paramMap.put("path", "/pages/ca-history");
                                    paramMap.put("query", "activityId=" + appUserShareActivity.getActivityId());
                                    break;
                                case 3:
                                case 4:
                                    log.info("渠道分享");
                                    if (2 == appUserShareActivity.getPageType()) {
                                        paramMap.put("path", "/pages/tabbar/tabbar");
                                        paramMap.put("query", "activityChannelId=" + appUserShareActivity.getActivityChannelId());
                                    } else {
                                        paramMap.put("query", "activityId=" + appUserShareActivity.getActivityId() +
                                                "&activityChannelId=" + appUserShareActivity.getActivityChannelId());
                                    }
                                    break;
                            }

                        } else {
                            paramMap.put("query", "activityId=" + appId);
                        }
                    }
                }
            }

            if (!"prod".equals(env)) {
                paramMap.put("env_version", "trial");
            }
            String result = HttpClientUtil.postJson(urlLink, paramMap, null, 3000, "utf8", 3, true);
            log.info(" 小程序的 URL Link appId ->{}| result ->{}", appId, result);
            if (StringUtils.isBlank(result)) {
                return "";
            }
            WechatUrlLinkResult wechatUrlLinkResult = JSON.parseObject(result, WechatUrlLinkResult.class);
            if (Objects.isNull(wechatUrlLinkResult)) {
                return "";
            }
            if (0 != wechatUrlLinkResult.getErrcode()) {
                log.error("【小程序的 URL Link】错误 code -> {} | errormsg ->{}", wechatUrlLinkResult.getErrcode(),
                        wechatUrlLinkResult.getErrmsg());
                return "";
            }
            if (type == 1) {
                Query query = new Query();
                query.addCriteria(Criteria.where("appId").is(wxAppId));
                AppUrlLink appUrlLink = this.mongoTemplate.findOne(query, AppUrlLink.class);
                if (Objects.nonNull(appUrlLink)) {
                    return appUrlLink.getUrl();
                }
                Date now = new Date();
                appUrlLink = new AppUrlLink();
                appUrlLink.setAppId(appId);
                appUrlLink.setUrl(wechatUrlLinkResult.getUrl_link());
                appUrlLink.setCreatedTime(now);
                appUrlLink.setUpdatedTime(now);
                this.mongoTemplate.save(appUrlLink);
            }

            log.info("【获取微信链接】appId ->{} end ");
            return wechatUrlLinkResult.getUrl_link();
        } catch (IOException e) {
            log.error("【小程序的 URL Link】错误 ", e);
            log.info("【获取微信链接】appId ->{} end ");
            return "";
        } catch (Exception e) {
            log.error("【小程序的 URL Link】错误 ", e);
            log.info("【获取微信链接】appId ->{} end ");
            return "";
        }
    }

    public Page<AppUrlLink> list(AppUrlLinkQueryVO req) {
        log.info(":>>>  开始获取应用链接:{}", req);
        Query query = new Query();
        if (StringUtils.isNotBlank(req.getAppId())) {
            query.addCriteria(Criteria.where("appId").is(req.getAppId()));
        }
        query.addCriteria(Criteria.where("deleted").ne(true));
        long count = mongoTemplate.count(query, AppUrlLink.class);
        PageRequest pageRequest = PageRequest.of(req.getPage() - 1, req.getPageSize());
//        query.with(new Sort(Sort.Direction.DESC, "createdTime"));
        Sort sort=Sort.by(Sort.Direction.DESC, "createdTime");
        query.with(sort);
        List<AppUrlLink> datas = mongoTemplate.find(query.with(pageRequest), AppUrlLink.class);
        if (!CollectionUtils.isEmpty(datas)) {
            for (AppUrlLink appUrlLink : datas) {
                Query queryApp = new Query();
                queryApp.addCriteria(Criteria.where("appId").is(appUrlLink.getAppId()));
                WechatConfigInfo wechatConfigInfo = mongoTemplate.findOne(queryApp, WechatConfigInfo.class);
                if (Objects.nonNull(wechatConfigInfo)) {
                    appUrlLink.setAppName(wechatConfigInfo.getName());
                }
            }
        }
        return PageableExecutionUtils.getPage(datas, pageRequest, () -> count);
    }

    public boolean delete(String id) {
        log.info(":>>>  开始删除应用链接:{}", id);
        Query query = new Query();
        query.addCriteria(Criteria.where("id").is(id));
        DeleteResult deleteResult = mongoTemplate.remove(query, AppUrlLink.class);
        return deleteResult.getDeletedCount() > 0 ? true : false;
    }

    public boolean generate(String id) {
        Query query = new Query();
        query.addCriteria(Criteria.where("id").is(id));
        AppUrlLink link = mongoTemplate.findOne(query, AppUrlLink.class);
        if (Objects.isNull(link)) {
            return false;
        }

        return true;
    }
}
